package bing.embedded.tomcat7;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;

public class EmbededContainer {
	private Tomcat tomcatServer = null;

	private final Map<Integer, Connector> serverConnectors;
	private Map<String, String> contexts;
	private String catalinaHomePath;
    private int defaultConnectorPort = 8080;
    
	public EmbededContainer(String basePath) {

		serverConnectors = new HashMap<Integer, Connector>();
		this.contexts = new HashMap<String, String>();
		this.catalinaHomePath = basePath;
	}

	public void addConnector(final Connector connector) {
		if (this.tomcatServer != null) {
			throw new RuntimeException("Cannot add a connector after the container has been started.");
		}
		if (!(connector instanceof Connector)) {
			throw new RuntimeException("This type of connector is not supported: " + connector.getClass().getName());
		}

		this.serverConnectors.put(connector.getPort(), connector);
	}

	public void setConexts(Map<String, String> contexts) {
		this.contexts = contexts;
	}

	public void setDefaultConnectorPort(int defaultConnectorPort) {
		this.defaultConnectorPort = defaultConnectorPort;
	}
	
	public void startup() throws Exception {
		if (tomcatServer != null) {
			this.shutdown();
		}

		//Tomcat中有一个默认测connector，所以可以不添加新的connector
		/*
		 * if (this.serverConnectors.size() == 0) {
		 *	throw new RuntimeException("Cannot start server, No connectors are defined.");
		}*/
		
		final File catalinaHomeDir = new File(catalinaHomePath);
		System.setProperty("catalina.home", catalinaHomeDir.getAbsolutePath());
		if (!catalinaHomeDir.canRead()) {
			throw new RuntimeException(
					"Unable to read expected catalina home at: " + catalinaHomeDir.getAbsolutePath());
		}
		final String webappsPath = catalinaHomeDir.getAbsolutePath() + File.separator + "webapps";
		final File webappsDir = new File(webappsPath);
		if (!webappsDir.canRead()) {
			throw new RuntimeException("Unable to read expected catalina home at: " + webappsDir.getAbsolutePath());
		}

		tomcatServer = new Tomcat();
		tomcatServer.setBaseDir(catalinaHomePath);
		
		final Engine baseEngine = this.tomcatServer.getEngine();
		baseEngine.setName("ptEngine");
		baseEngine.setDefaultHost("ptHost");
		
		final Host baseHost = new StandardHost();
		baseHost.setName("ptHost");
		baseHost.setAppBase("webapps");
		baseEngine.addChild(baseHost);
		
		for (Map.Entry<String, String> entry : contexts.entrySet()) {
			//this.tomcatServer.addContext(baseHost, entry.getKey(), entry.getValue());
			this.tomcatServer.addWebapp(baseHost, entry.getKey(), entry.getValue());
		}
		
		//this.tomcatServer.getService().setContainer(baseEngine);
		//

		//final Map<ObjectName, Integer> connectorBeanNameToMaxThreads = new HashMap<ObjectName, Integer>();

		//1. Tomcat默认有一个connector，默认端口为8080；如果不想使用默认connector或需要多个connector实例，
		//可以使用下面的代码进行添加。
		/*Service service = this.tomcatServer.getService();
		for (Connector connector : serverConnectors.values()) {
			service.addConnector(connector);
			
		}*/
		
		//2. 有一个默认的connector，默认端口为8080,在这里可以更改默认端口
		this.tomcatServer.setPort(defaultConnectorPort);  
		
		this.tomcatServer.start();
		System.out.println("embeded tomcat server started.");
		this.tomcatServer.getServer().await();

	}

	public void shutdown() throws Exception {
		try {
			tomcatServer.stop();
		} catch (LifecycleException ex) {
			ex.printStackTrace();
			// log.error(ex.getMessage());
			throw ex;
		}
		// log.info("Tomcat stoped");
	}

}
